<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:t="http://kadm.com.ua/XMLSchema/Text">

    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />

    <xsl:template match="/">
        <t:file>
		<xsl:apply-templates />
        </t:file>
    </xsl:template>

    <xsl:template match="grammar">
        <t:l>require_once 'parser.php';</t:l>
        <t:l></t:l>
        <t:l>class <xsl:value-of select="@name" /> extends Parser</t:l>
        <t:l>{</t:l>
        <t:l></t:l>
        <t:block>
            <t:l>function __construct()</t:l>
            <t:l>{</t:l>
            <t:block>
                <t:l>parent::__construct();</t:l>
                <t:l>$this->main = "<xsl:value-of select="rule[1]/@NT" />";</t:l>
            </t:block>
            <t:l>}</t:l>
            <xsl:apply-templates />
        </t:block>
        <t:l></t:l>
        <t:l>}</t:l>
    </xsl:template>

    <xsl:template match="rule">
        <t:l></t:l>
        <t:l>function <xsl:value-of select="@NT" />()</t:l>
        <t:l>{</t:l>
        <t:block>
            <t:l>$this->createChild('<xsl:value-of select="@NT" />');</t:l>
            <t:l></t:l>
			<xsl:apply-templates />
            <t:l></t:l>
            <t:l>$this->endChild();</t:l>
        </t:block>
        <t:l>}</t:l>
    </xsl:template>

    <xsl:template match="option">
        <t:l>if (<xsl:apply-templates select="." mode="first-cond" />) {</t:l>
        <t:block>
            <xsl:apply-templates />
        </t:block>
        <t:l>}</t:l>
    </xsl:template>

    <xsl:template match="choose">
        <t:l>switch (true) {</t:l>
        <t:block>
            <xsl:apply-templates />
            <t:l>default:</t:l>
            <t:block>
                <t:l>$this->Error();</t:l>
            </t:block>
        </t:block>
        <t:l>}</t:l>
    </xsl:template>

    <xsl:template match="case">
        <t:l>case <xsl:apply-templates select="." mode="first-cond" />:</t:l>
        <t:block>
            <xsl:apply-templates />
            <t:l>break;</t:l>
            <t:l></t:l>
        </t:block>
    </xsl:template>

    <xsl:template match="term">
        <t:l>if ($this->Ch() == '<xsl:value-of select="." />') {</t:l>
        <t:block>
            <t:l>$this->NextCh();</t:l>
        </t:block>
        <t:l>} else {</t:l>
        <t:block>
            <t:l>$this->Error();</t:l>
        </t:block>
        <t:l>}</t:l>
    </xsl:template>

    <xsl:template match="NT">
        <t:l>$this-><xsl:value-of select="." />();</t:l>
    </xsl:template>

    <xsl:template match="multi">
        <t:l>while (<xsl:apply-templates select="." mode="first-cond" />) {</t:l>
        <t:block>
            <xsl:apply-templates />
        </t:block>
        <t:l>}</t:l>
    </xsl:template>

    <xsl:template match="*" mode="first-cond">
        <xsl:text>in_array($this->Ch(), array ( </xsl:text>
		<xsl:apply-templates select="." mode="first" />
        <xsl:text>))</xsl:text>
    </xsl:template>

    <xsl:template match="* | option | multi | rule | case | choose" mode="first">
        <xsl:apply-templates mode="first" />
    </xsl:template>

     <xsl:template match="sequence" mode="first">
        <xsl:apply-templates select="*[1]" mode="first" />
    </xsl:template>

   <xsl:template match="NT" mode="first">
        <xsl:variable name="NT" select="text()" />
        <xsl:apply-templates select="//rule[@NT = $NT]" mode="first" />
    </xsl:template>

    <xsl:template match="term" mode="first">
        <xsl:text>'</xsl:text>
		<xsl:value-of select="substring(text(),1,1)" />
        <xsl:text>', </xsl:text>
    </xsl:template>

</xsl:stylesheet>